﻿using MvvmCross.Core.ViewModels;
using Sidvall.AuthorizationManager.UI.Entities;
using Sidvall.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Sidvall.AuthorizationManager.UI.ViewModels
{
    public partial class AuthorizationScopeViewModel
    {
        #region Public Members

        #region Title

        public string Title
        {
            get
            {
                if (this.ActiveTreeItem == null)
                {
                    return "Authorization Scopes";
                }
                else
                {
                    return this.ActiveTreeItem.FullName;
                }
            }
        }

        #endregion
        #region TreeItems

        private TreeItemCollection _TreeItems;
        public TreeItemCollection TreeItems
        {
            get
            {
                return _TreeItems;
            }
            set
            {
                if (_TreeItems != null)
                    _TreeItems.CollectionChanging -= OnTreeItemsCollectionChanging;
                _TreeItems = value;
                if (_TreeItems != null)
                    _TreeItems.CollectionChanging += OnTreeItemsCollectionChanging;
                RaisePropertyChanged("TreeItems");
                RaisePropertyChanged("Title");
            }
        }

        #endregion
        #region ActiveServer

        private ServerConnection _ActiveServer;
        public ServerConnection ActiveServer
        {
            get
            {
                return _ActiveServer;
            }
            set
            {
                _ActiveServer = value;
                if (_ActiveServer != null)
                {
                    _ActiveAuthorizationScope = null;
                }
                InitializeTreeItem();
            }
        }

        #endregion
        #region ActiveAuthorizationScope

        private AuthorizationScope _ActiveAuthorizationScope;
        public AuthorizationScope ActiveAuthorizationScope
        {
            get
            {
                return _ActiveAuthorizationScope;
            }
            set
            {
                if (_ActiveAuthorizationScope != null)
                    _ActiveAuthorizationScope.PropertyChanged -= OnActiveAuthorizationScopePropertyChanged;
                _ActiveAuthorizationScope = value;
                if (_ActiveAuthorizationScope != null)
                {
                    _ActiveAuthorizationScope.PropertyChanged += OnActiveAuthorizationScopePropertyChanged;
                    _ActiveServer = null;
                }
                InitializeTreeItem();
            }
        }

        #endregion
        #region ActiveTreeItem

        private TreeItem _ActiveTreeItem;
        public TreeItem ActiveTreeItem
        {
            get
            {
                return _ActiveTreeItem;
            }
            set
            {
                _ActiveTreeItem = value;
                RaisePropertyChanged("ActiveTreeItem");
                RaisePropertyChanged("Title");
            }
        }

        #endregion
        #region ActiveResourceAction

        private AuthorizationScopeResourceAction _ActiveResourceAction;
        public AuthorizationScopeResourceAction ActiveResourceAction
        {
            get
            {
                return _ActiveResourceAction;
            }
            set
            {
                _ActiveResourceAction = value;
                RaisePropertyChanged("ActiveResourceAction");
            }
        }

        #endregion
        #region ActiveResourceItem

        private AuthorizationScopeResourceItem _ActiveResourceItem;
        public AuthorizationScopeResourceItem ActiveResourceItem
        {
            get
            {
                return _ActiveResourceItem;
            }
            set
            {
                _ActiveResourceItem = value;
                RaisePropertyChanged("ActiveResourceItem");
            }
        }

        #endregion
        #region ActiveUser

        private AuthorizationScopeUser _ActiveUser;
        public AuthorizationScopeUser ActiveUser
        {
            get
            {
                return _ActiveUser;
            }
            set
            {
                _ActiveUser = value;
                RaisePropertyChanged("ActiveUser");
                InitializeActiveUser();
            }
        }

        #endregion
        #region ActiveUserClaims

        private ClaimCollection _ActiveUserClaims;
        public ClaimCollection ActiveUserClaims
        {
            get
            {
                return _ActiveUserClaims;
            }
            private set
            {
                if (_ActiveUserClaims != null)
                    _ActiveUserClaims.ChildChanged -= OnActiveUserClaimsChildChanged;
                _ActiveUserClaims = value;
                if (_ActiveUserClaims != null)
                    _ActiveUserClaims.ChildChanged += OnActiveUserClaimsChildChanged;
                RaisePropertyChanged("ActiveUserClaims");
            }
        }

        #endregion
        #region ActiveUserContext

        private string _ActiveUserContext;
        public string ActiveUserContext
        {
            get
            {
                return _ActiveUserContext;
            }
            set
            {
                string formattedValue;
                try
                {
                    var item = Sidvall.Serialization.SerializerManager.Current.Deserialize(value);
                    if (item != null)
                        formattedValue = Sidvall.Serialization.SerializerManager.Current.SerializeObject(item, Serialization.Formatting.Indented);
                    else
                        formattedValue = value;
                }
                catch
                {
                    formattedValue = value;
                }
                if (_ActiveUserContext == formattedValue)
                    return;
                _ActiveUserContext = formattedValue;
                RaisePropertyChanged("ActiveUserContext");
                this.ActiveUser.UserContext = value;
            }
        }

        #endregion
        #region InformationIsVisible

        public bool InformationIsVisible
        {
            get
            {
                if (_AuthorizationScopeIsVisible)
                    return false;
                if ((this.ServerIsVisible) || (this.AuthorizationScopeIsVisible))
                    return false;
                return true;
            }
        }

        #endregion
        #region ServerIsVisible

        public bool ServerIsVisible
        {
            get
            {
                if (_AuthorizationScopeIsVisible)
                    return false;
                if (this.ActiveServer != null)
                    return true;
                return false;
            }
        }

        #endregion
        #region AuthorizationScopeIsVisible

        public bool AuthorizationScopeIsVisible
        {
            get
            {
                if (_AuthorizationScopeIsVisible)
                    return true;
                if (this.ActiveAuthorizationScope != null)
                    return true;
                return false;
            }
        }

        #endregion
        #region ResourceActionListIsVisible

        public bool ResourceActionListIsVisible
        {
            get
            {
                return _ResourceActionListIsVisible;
            }
            set
            {
                _ResourceActionListIsVisible = value;
                RaisePropertyChanged("ResourceActionListIsVisible");
            }
        }

        #endregion
        #region ResourceItemListIsVisible

        public bool ResourceItemListIsVisible
        {
            get
            {
                return _ResourceItemListIsVisible;
            }
            set
            {
                _ResourceItemListIsVisible = value;
                RaisePropertyChanged("ResourceItemListIsVisible");
            }
        }

        #endregion
        #region UserListIsVisible

        public bool UserListIsVisible
        {
            get
            {
                return _UserListIsVisible;
            }
            set
            {
                _UserListIsVisible = value;
                RaisePropertyChanged("UserListIsVisible");
            }
        }

        #endregion
        #region CanSave

        public bool CanSave
        {
            get
            {
                if (this.ActiveAuthorizationScope != null)
                    return this.ActiveAuthorizationScope.DataRowStateIsDirty;
                return false;
            }
        }

        #endregion
        #region CanDelete

        public bool CanDelete
        {
            get
            {
                if ((this.ActiveAuthorizationScope != null) && (this.ActiveAuthorizationScope.AuthorizationScopeId != null))
                    return true;
                return false;
            }
        }

        #endregion
        #region CanAddTreeItem

        public bool CanAddTreeItem
        {
            get
            {
                if (this.ActiveServer != null)
                    return true;
                return false;
            }
        }

        #endregion
        #region AddTreeItemCaption

        public string AddTreeItemCaption
        {
            get
            {
                if (this.ActiveServer != null)
                    return "Add Auth Scope";
                return null;
            }
        }

        #endregion
        #region AuthorizationScopeAccessLevels

        private Sidvall.Data.KeyValueCollection<string, Data.AuthorizationScopeAccessLevel> _AuthorizationScopeAccessLevels;
        public Sidvall.Data.KeyValueCollection<string, Data.AuthorizationScopeAccessLevel> AuthorizationScopeAccessLevels
        {
            get
            {
                if (_AuthorizationScopeAccessLevels == null)
                    this.AuthorizationScopeAccessLevels = Sidvall.Data.KeyValueManager.FromEnum<Data.AuthorizationScopeAccessLevel>();
                return _AuthorizationScopeAccessLevels;
            }
            set
            {
                _AuthorizationScopeAccessLevels = value;
                RaisePropertyChanged("AuthorizationScopeAccessLevels");
            }
        }

        #endregion
        #region ResourceAccessLevels

        private Sidvall.Data.KeyValueCollection<string, Data.ResourceAccessLevel> _ResourceAccessLevels;
        public Sidvall.Data.KeyValueCollection<string, Data.ResourceAccessLevel> ResourceAccessLevels
        {
            get
            {
                if (_ResourceAccessLevels == null)
                    this.ResourceAccessLevels = Sidvall.Data.KeyValueManager.FromEnum<Data.ResourceAccessLevel>();
                return _ResourceAccessLevels;
            }
            set
            {
                _ResourceAccessLevels = value;
                RaisePropertyChanged("ResourceAccessLevels");
            }
        }

        #endregion
        #region ValidClaims

        private Sidvall.Security.ClaimCollection _ValidClaims;
        public Sidvall.Security.ClaimCollection ValidClaims
        {
            get
            {
                if (_ValidClaims == null)
                    this.ValidClaims = new Sidvall.Security.ClaimCollection();
                return _ValidClaims;
            }
            set
            {
                _ValidClaims = value;
                RaisePropertyChanged("ValidClaims");
            }
        }

        #endregion
        #region ValidUserClaims

        private Sidvall.Security.ClaimCollection _ValidUserClaims;
        public Sidvall.Security.ClaimCollection ValidUserClaims
        {
            get
            {
                if (_ValidUserClaims == null)
                    this.ValidUserClaims = new Sidvall.Security.ClaimCollection();
                return _ValidUserClaims;
            }
            set
            {
                _ValidUserClaims = value;
                RaisePropertyChanged("ValidUserClaims");
            }
        }

        #endregion
        #region JsonContent

        private string _JsonContent;
        public string JsonContent
        {
            get
            {
                return _JsonContent;
            }
            set
            {
                _JsonContent = value;
                RaisePropertyChanged("JsonContent");
            }
        }

        #endregion
        #region JsonContentIncludeResourceItems

        private bool _JsonContentIncludeResourceItems;
        public bool JsonContentIncludeResourceItems
        {
            get
            {
                return _JsonContentIncludeResourceItems;
            }
            set
            {
                _JsonContentIncludeResourceItems = value;
                RaisePropertyChanged("JsonContentIncludeResourceItems");
                InitializeJsonContent();
            }
        }

        #endregion
        #region JsonContentIncludeUserItems

        private bool _JsonContentIncludeUserItems;
        public bool JsonContentIncludeUserItems
        {
            get
            {
                return _JsonContentIncludeUserItems;
            }
            set
            {
                _JsonContentIncludeUserItems = value;
                RaisePropertyChanged("JsonContentIncludeUserItems");
                InitializeJsonContent();
            }
        }

        #endregion
        #region JsonContentIsFormatted

        private bool _JsonContentIsFormatted;
        public bool JsonContentIsFormatted
        {
            get
            {
                return _JsonContentIsFormatted;
            }
            set
            {
                _JsonContentIsFormatted = value;
                RaisePropertyChanged("JsonContentIsFormatted");
                InitializeJsonContent();
            }
        }

        #endregion
        #region AuthorizationContext

        private AuthorizationContext _AuthorizationContext;
        public AuthorizationContext AuthorizationContext
        {
            get
            {
                return _AuthorizationContext;
            }
            set
            {
                _AuthorizationContext = value;
                RaisePropertyChanged("AuthorizationContext");
            }
        }

        #endregion
        #region ComparisonOperators

        private Sidvall.Data.KeyValueCollection<string, Sidvall.Data.ComparisonOperator> _ComparisonOperators;
        public Sidvall.Data.KeyValueCollection<string, Sidvall.Data.ComparisonOperator> ComparisonOperators
        {
            get
            {
                if (_ComparisonOperators == null)
                    this.ComparisonOperators = Sidvall.Data.KeyValueManager.FromEnum<Sidvall.Data.ComparisonOperator>();
                return _ComparisonOperators;
            }
            set
            {
                _ComparisonOperators = value;
                RaisePropertyChanged("ComparisonOperators");
            }
        }

        #endregion
        #region ResourceActionOptions

        private ActionOptionCollection _ResourceActionOptions;
        public ActionOptionCollection ResourceActionOptions
        {
            get
            {
                return _ResourceActionOptions;
            }
            set
            {
                _ResourceActionOptions = value;
                RaisePropertyChanged("ResourceActionOptions");
            }
        }

        #endregion
        #region ResourceItemActionOptions

        private ActionOptionCollection _ResourceItemActionOptions;
        public ActionOptionCollection ResourceItemActionOptions
        {
            get
            {
                return _ResourceItemActionOptions;
            }
            set
            {
                _ResourceItemActionOptions = value;
                RaisePropertyChanged("ResourceItemActionOptions");
            }
        }

        #endregion
        #region ResourceItemActionPolicies

        private Sidvall.Data.KeyValueCollection<string, Sidvall.AuthorizationManager.Data.ResourceItemActionPolicy> _ResourceItemActionPolicies;
        public Sidvall.Data.KeyValueCollection<string, Sidvall.AuthorizationManager.Data.ResourceItemActionPolicy> ResourceItemActionPolicies
        {
            get
            {
                if (_ResourceItemActionPolicies == null)
                    this.ResourceItemActionPolicies = Sidvall.Data.KeyValueManager.FromEnum<Sidvall.AuthorizationManager.Data.ResourceItemActionPolicy>();
                return _ResourceItemActionPolicies;
            }
            set
            {
                _ResourceItemActionPolicies = value;
                RaisePropertyChanged("ResourceItemActionPolicies");
            }
        }

        #endregion
        #region MissingUserPolicies

        private Sidvall.Data.KeyValueCollection<string, Data.MissingUserPolicy> _MissingUserPolicies;
        public Sidvall.Data.KeyValueCollection<string, Data.MissingUserPolicy> MissingUserPolicies
        {
            get
            {
                if (_MissingUserPolicies == null)
                    this.MissingUserPolicies = Sidvall.Data.KeyValueManager.FromEnum<Data.MissingUserPolicy>();
                return _MissingUserPolicies;
            }
            set
            {
                _MissingUserPolicies = value;
                RaisePropertyChanged("MissingUserPolicies");
            }
        }

        #endregion

        #region ExportSettingsCommand

        public ICommand ExportSettingsCommand
        {
            get
            {
                return new MvxCommand(async () => await ExportSettingsAsync());
            }
        }

        #endregion
        #region ExportSettingsAsync

        public async Task ExportSettingsAsync()
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            var item = new Net.Services.V1.AuthorizationScope();
            item.Import(this.ActiveAuthorizationScope, Sidvall.Data.CopySettings.FullCopyAll(Sidvall.Data.DataRowContextOption.None, null));
            await ViewModelManager.ExportSettingsAsync("AuthScope_" + this.ActiveAuthorizationScope.Name + ".txt", item);
        }

        #endregion
        #region ImportSettingsCommand

        public ICommand ImportSettingsCommand
        {
            get
            {
                return new MvxCommand(async () => await ImportSettingsAsync());
            }
        }

        #endregion
        #region ImportSettingsAsync

        public async Task ImportSettingsAsync()
        {
            Task task = null;
            if (this.ActiveServer == null)
                return;
            try
            {
                var content = await ViewModelManager.ImportSettingsAsync();
                if (string.IsNullOrWhiteSpace(content))
                    return;
                var data = Sidvall.Serialization.SerializerManager.Current.Deserialize<Net.Services.V1.AuthorizationScope>(content);
                var item = new Sidvall.AuthorizationManager.UI.Entities.AuthorizationScope();
                var copySettings = new CopySettings(Sidvall.Business.FieldCopyOptions.ManualNonPrimaryKeys, Sidvall.Data.DataRowContextOption.None, null, true, true,
                    MergeOption.Append, DataRowFilters.All, false);
                item.Import(data, copySettings);
                item.ServerConnectionId = this.ActiveServer.ServerConnectionId;
                item = await item.SaveItemAsync();
                await ReloadAsync();
                var treeItem = (from o in this.TreeItems
                                where (o.ServerConnectionId == item.ServerConnectionId) && (o.AuthorizationScopeId == item.AuthorizationScopeId)
                                select o).FirstOrDefault();
                if (treeItem != null)
                    this.ActiveTreeItem = treeItem;
            }
            catch (System.Exception ex)
            {
                task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Import Error", ex);
            }
            if (task != null)
                await task;
        }

        #endregion

        #region AddResourceActionCommand

        public ICommand AddResourceActionCommand
        {
            get
            {
                return new MvxCommand(AddResourceAction);
            }
        }

        #endregion
        #region AddResourceAction

        public void AddResourceAction()
        {
            AuthorizationScopeResourceAction item;

            if (this.ActiveAuthorizationScope == null)
                return;

            item = new AuthorizationScopeResourceAction()
            {
                AccessLevel = Data.ResourceAccessLevel.Public,
                IsEnabled = true,
                ValidForResourceActionItems = true,
            };
            item.LoadAuthorizationScopeResourceActionClaims(new AuthorizationScopeResourceActionClaimCollection());
            if (this.ActiveAuthorizationScope.AuthorizationScopeId != null)
                item.AuthorizationScopeId = this.ActiveAuthorizationScope.AuthorizationScopeId.Value;
            this.ActiveAuthorizationScope.AuthorizationScopeResourceActions.Add(item);
            this.ActiveResourceAction = item;
        }

        #endregion
        #region DeleteResourceActionCommand

        public ICommand DeleteResourceActionCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeResourceAction>(DeleteResourceAction);
            }
        }

        #endregion
        #region DeleteResourceAction

        public void DeleteResourceAction(AuthorizationScopeResourceAction item)
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            if (item == null)
                return;
            this.ActiveAuthorizationScope.AuthorizationScopeResourceActions.Remove(item);
        }

        #endregion
        #region ShowResourceActionListCommand

        public ICommand ShowResourceActionListCommand
        {
            get
            {
                return new MvxCommand(ShowResourceActionList);
            }
        }

        #endregion
        #region ShowResourceActionList

        public void ShowResourceActionList()
        {
            this.ResourceActionListIsVisible = true;
        }

        #endregion

        #region AddResourceItemCommand

        public ICommand AddResourceItemCommand
        {
            get
            {
                return new MvxCommand(AddResourceItem);
            }
        }

        #endregion
        #region AddResourceItem

        public void AddResourceItem()
        {
            AuthorizationScopeResourceItem item;

            if (this.ActiveAuthorizationScope == null)
                return;

            item = new AuthorizationScopeResourceItem()
            {
                AccessLevel = Data.ResourceAccessLevel.Public,
                IsEnabled = true,
            };
            item.LoadAuthorizationScopeResourceItemClaims(new AuthorizationScopeResourceItemClaimCollection());
            if (this.ActiveAuthorizationScope.AuthorizationScopeId != null)
                item.AuthorizationScopeId = this.ActiveAuthorizationScope.AuthorizationScopeId.Value;
            this.ActiveAuthorizationScope.AuthorizationScopeResourceItems.Add(item);
            this.ActiveResourceItem = item;
        }

        #endregion
        #region DeleteResourceItemCommand

        public ICommand DeleteResourceItemCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeResourceItem>(DeleteResourceItem);
            }
        }

        #endregion
        #region DeleteResourceItem

        public void DeleteResourceItem(AuthorizationScopeResourceItem item)
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            if (item == null)
                return;
            this.ActiveAuthorizationScope.AuthorizationScopeResourceItems.Remove(item);
        }

        #endregion
        #region ShowResourceItemListCommand

        public ICommand ShowResourceItemListCommand
        {
            get
            {
                return new MvxCommand(ShowResourceItemList);
            }
        }

        #endregion
        #region ShowResourceItemList

        public void ShowResourceItemList()
        {
            this.ResourceItemListIsVisible = true;
        }

        #endregion

        #region AddClaimCommand

        public ICommand AddClaimCommand
        {
            get
            {
                return new MvxCommand(AddClaim);
            }
        }

        #endregion
        #region AddClaim

        public void AddClaim()
        {
            AuthorizationScopeResourceActionClaim item;

            if (this.ActiveResourceAction == null)
                return;

            item = new AuthorizationScopeResourceActionClaim()
            {
                IsEnabled = true,
            };
            if (this.ActiveResourceAction.AuthorizationScopeResourceActionId != null)
                item.AuthorizationScopeResourceActionId = this.ActiveResourceAction.AuthorizationScopeResourceActionId.Value;
            this.ActiveResourceAction.AuthorizationScopeResourceActionClaims.Add(item);
        }

        #endregion
        #region DeleteClaimCommand

        public ICommand DeleteClaimCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeResourceActionClaim>(DeleteClaim);
            }
        }

        #endregion
        #region DeleteClaim

        public void DeleteClaim(AuthorizationScopeResourceActionClaim item)
        {
            if (this.ActiveResourceAction == null)
                return;
            if (item == null)
                return;
            this.ActiveResourceAction.AuthorizationScopeResourceActionClaims.Remove(item);
        }

        #endregion
        #region EditClaimsCommand

        public ICommand EditClaimsCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeResourceAction>(EditClaims);
            }
        }

        #endregion
        #region EditClaims

        public void EditClaims(AuthorizationScopeResourceAction item)
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            if (item == null)
                return;
            this.ActiveResourceAction = item;
            this.ResourceActionListIsVisible = false;
        }

        #endregion

        #region AddItemClaimCommand

        public ICommand AddItemClaimCommand
        {
            get
            {
                return new MvxCommand(AddItemClaim);
            }
        }

        #endregion
        #region AddItemClaim

        public void AddItemClaim()
        {
            AuthorizationScopeResourceItemClaim item;

            if (this.ActiveResourceItem == null)
                return;

            item = new AuthorizationScopeResourceItemClaim()
            {
                IsEnabled = true,
            };
            if (this.ActiveResourceItem.AuthorizationScopeResourceItemId != null)
                item.AuthorizationScopeResourceItemId = this.ActiveResourceItem.AuthorizationScopeResourceItemId.Value;
            this.ActiveResourceItem.AuthorizationScopeResourceItemClaims.Add(item);
        }

        #endregion
        #region DeleteItemClaimCommand

        public ICommand DeleteItemClaimCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeResourceItemClaim>(DeleteItemClaim);
            }
        }

        #endregion
        #region DeleteItemClaim

        public void DeleteItemClaim(AuthorizationScopeResourceItemClaim item)
        {
            if (this.ActiveResourceItem == null)
                return;
            if (item == null)
                return;
            this.ActiveResourceItem.AuthorizationScopeResourceItemClaims.Remove(item);
        }

        #endregion
        #region EditItemClaimsCommand

        public ICommand EditItemClaimsCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeResourceItem>(EditItemClaims);
            }
        }

        #endregion
        #region EditItemClaims

        public void EditItemClaims(AuthorizationScopeResourceItem item)
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            if (item == null)
                return;
            this.ActiveResourceItem = item;
            this.ResourceItemListIsVisible = false;
        }

        #endregion

        #region AddExportCommand

        public ICommand AddExportCommand
        {
            get
            {
                return new MvxCommand(AddExport);
            }
        }

        #endregion
        #region AddExport

        public void AddExport()
        {
            AuthorizationScopeExport item;

            if (this.ActiveAuthorizationScope == null)
                return;

            item = new AuthorizationScopeExport()
            {
                IsEnabled = true,
                IncludeResourceItems = true,
                CreateMissingFile = false,
            };
            if (this.ActiveAuthorizationScope.AuthorizationScopeId != null)
                item.AuthorizationScopeId = this.ActiveAuthorizationScope.AuthorizationScopeId.Value;
            this.ActiveAuthorizationScope.AuthorizationScopeExports.Add(item);
        }

        #endregion
        #region DeleteExportCommand

        public ICommand DeleteExportCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeExport>(DeleteExport);
            }
        }

        #endregion
        #region DeleteExport

        public void DeleteExport(AuthorizationScopeExport item)
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            if (item == null)
                return;
            this.ActiveAuthorizationScope.AuthorizationScopeExports.Remove(item);
        }

        #endregion
        #region ExportToFilesCommand

        public ICommand ExportToFilesCommand
        {
            get
            {
                return new MvxCommand(async () => await ExportToFilesAsync());
            }
        }

        #endregion
        #region ExportToFilesAsync

        public async Task ExportToFilesAsync()
        {
            Task task = null;
            if (this.ActiveAuthorizationScope == null)
                return;
            using (var busyManager = new BusyManager(this))
            {
                try
                {
                    foreach (var exportFile in this.ActiveAuthorizationScope.AuthorizationScopeExports)
                    {
                        if (!exportFile.IsEnabled)
                            continue;
                        if (string.IsNullOrWhiteSpace(exportFile.XmlNode))
                        {
                            if ((!exportFile.CreateMissingFile) && (!await Sidvall.SystemContext.Current.SystemStorageManager.FileExistsAsync(exportFile.FilePath)))
                                continue;
                            await Sidvall.AuthorizationManager.Workflow.ExportWorkItemProvider.ExecuteAsync(exportFile.FilePath, this.ActiveAuthorizationScope,
                                exportFile.IncludeResourceItems, exportFile.IncludeUserItems, false);
                        }
                        else
                        {
                            await Sidvall.AuthorizationManager.Workflow.ExportWorkItemProvider.ExecuteAsync(exportFile.FilePath, exportFile.XmlNode, this.ActiveAuthorizationScope,
                                exportFile.IncludeResourceItems, exportFile.IncludeUserItems, false);
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
                }
                if (task != null)
                    await task;
            }
        }

        #endregion

        #region ExportJsonContentCommand

        public ICommand ExportJsonContentCommand
        {
            get
            {
                return new MvxCommand(async () => await ExportJsonContentAsync());
            }
        }

        #endregion
        #region ExportJsonContentAsync

        public async Task ExportJsonContentAsync()
        {
            Task task = null;
            string filePath;

            if (this.ActiveAuthorizationScope == null)
                return;
            try
            {
                filePath = await Sidvall.UI.SystemContext.Current.DialogManager.SaveFileAsync("Text files (*.txt)|*.txt|All Files (*.*)|*.*", "*.txt");
                if (string.IsNullOrWhiteSpace(filePath))
                    return;
                await Sidvall.AuthorizationManager.Workflow.ExportWorkItemProvider.ExecuteAsync(filePath, this.ActiveAuthorizationScope, this.JsonContentIncludeResourceItems,
                    this.JsonContentIncludeUserItems, this.JsonContentIsFormatted);
            }
            catch (System.Exception ex)
            {
                task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
            }
            if (task != null)
                await task;
        }

        #endregion
        #region InitializeJsonContent

        public void InitializeJsonContent()
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            this.JsonContent = Sidvall.AuthorizationManager.Workflow.ExportWorkItemProvider.GetJsonContent(this.ActiveAuthorizationScope, this.JsonContentIncludeResourceItems,
                this.JsonContentIncludeUserItems, this.JsonContentIsFormatted);
        }

        #endregion

        #region AuthorizeUserCommand

        public ICommand AuthorizeUserCommand
        {
            get
            {
                return new MvxCommand(async () => await AuthorizeUserAsync());
            }
        }

        #endregion
        #region AuthorizeUserAsync

        public async Task AuthorizeUserAsync()
        {
            Sidvall.Security.CustomIdentity identity;
            bool isAuthorized;

            if (this.ActiveAuthorizationScope == null)
                return;
            using (var busyManager = new BusyManager(this))
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(this.AuthorizationContext.UserName))
                    {
                        identity = new Sidvall.Security.CustomIdentity()
                        {
                            Name = this.AuthorizationContext.UserName,
                            IsAuthenticated = true,
                        };
                    }
                    else
                    {
                        identity = new Sidvall.Security.CustomIdentity()
                        {
                            IsAuthenticated = false,
                        };
                    }
                    var principal = new Sidvall.Security.CustomPrincipal(identity);
                    if (!string.IsNullOrWhiteSpace(this.AuthorizationContext.ClaimType))
                    {
                        var claim = new Sidvall.Security.Claim()
                        {
                            ClaimType = this.AuthorizationContext.ClaimType,
                            Value = this.AuthorizationContext.ClaimValue,
                        };
                        Sidvall.SystemContext.Current.ClaimManager.AddClaim(principal.Identity, claim);
                    }
                    var item = new Sidvall.AuthorizationManager.Security.AuthorizationProvider();
                    item.LoadFromAuthorizationScope(this.ActiveAuthorizationScope, false, false);
                    var manager = new Sidvall.Security.AuthorizationManager(item);
                    var serverConnection = ParameterManager.GetServerConnection(this.ActiveAuthorizationScope.ServerConnectionId.Value);
                    Sidvall.AuthorizationManager.SystemContext.Current.DataPortalStrategyFacade.MasterServerConnection = Sidvall.AuthorizationManager.SystemContext.Current.GetServerConnection(serverConnection);
                    if (string.IsNullOrWhiteSpace(this.AuthorizationContext.ResourceItemId))
                    {
                        isAuthorized = await manager.IsAuthorizedAsync(principal, this.AuthorizationContext.Resource, this.AuthorizationContext.Action, this.AuthorizationContext.SubAction);
                    }
                    else
                    {
                        isAuthorized = await manager.IsAuthorizedAsync(principal, this.AuthorizationContext.Resource, this.AuthorizationContext.Action, this.AuthorizationContext.SubAction,
                            this.AuthorizationContext.ResourceItemId);
                    }
                    Sidvall.AuthorizationManager.SystemContext.Current.DataPortalStrategyFacade.MasterServerConnection = null;
                    if (isAuthorized)
                        await Sidvall.UI.SystemContext.Current.DialogManager.ShowMessageAsync("Authorization - Success", "User was authorized!", Sidvall.UI.Dialogs.MessageType.Information);
                    else
                        await Sidvall.UI.SystemContext.Current.DialogManager.ShowMessageAsync("Authorization - Failed", "User was not authorized!", Sidvall.UI.Dialogs.MessageType.Information);
                }
                catch (System.Exception ex)
                {
                    await Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
                }
                finally
                {
                    Sidvall.AuthorizationManager.SystemContext.Current.DataPortalStrategyFacade.MasterServerConnection = null;
                }
            }
        }

        #endregion

        #region AddTreeItemCommand

        public ICommand AddTreeItemCommand
        {
            get
            {
                return new MvxCommand(async () => await AddTreeItemAsync());
            }
        }

        #endregion
        #region AddTreeItemAsync

        public async Task AddTreeItemAsync()
        {
            AuthorizationScope item;
            TreeItem treeItem;
            Task task = null;

            treeItem = null;
            using (var busyManager = new BusyManager(this))
            {
                try
                {
                    if (this.ActiveServer != null)
                    {
                        item = new AuthorizationScope()
                        {
                            ServerConnectionId = this.ActiveServer.ServerConnectionId,
                            Name = "** New Authorization Scope **",
                            IsEnabled = true,
                            DefaultResourceActionAccessLevel = Sidvall.AuthorizationManager.Data.AuthorizationScopeAccessLevel.Public,
                            DefaultResourceItemAccessLevel = Sidvall.AuthorizationManager.Data.AuthorizationScopeAccessLevel.Public,
                            ResourceItemPolicyId = Sidvall.AuthorizationManager.Data.ResourceItemActionPolicy.UseItemsAndActionsWithFilter,
                        };
                        item = await item.SaveItemAsync();
                        await ReloadAsync();
                        treeItem = (from o in this.TreeItems
                                    where (o.ServerConnectionId == item.ServerConnectionId) && (o.AuthorizationScopeId == item.AuthorizationScopeId)
                                    select o).FirstOrDefault();
                    }
                }
                catch (System.Exception ex)
                {
                    task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
                }
                if (task != null)
                    await task;
            }
            if (treeItem != null)
                this.ActiveTreeItem = treeItem;
        }

        #endregion
        #region DeleteActiveTreeItemCommand

        public ICommand DeleteActiveTreeItemCommand
        {
            get
            {
                return new MvxCommand(async () => await DeleteActiveTreeItemAsync());
            }
        }

        #endregion
        #region DeleteActiveTreeItemAsync

        public async Task DeleteActiveTreeItemAsync()
        {
            await DeleteTreeItemAsync(this.ActiveTreeItem);
        }

        #endregion
        #region SaveActiveTreeItemCommand

        public ICommand SaveActiveTreeItemCommand
        {
            get
            {
                return new MvxCommand(async () => await SaveActiveTreeItemAsync());
            }
        }

        #endregion
        #region SaveActiveTreeItemAsync

        public async Task SaveActiveTreeItemAsync()
        {
            Task task = null;
            using (var busyManager = new BusyManager(this))
            {
                try
                {
                    if (this.ActiveAuthorizationScope != null)
                    {
                        this.ActiveAuthorizationScope = await this.ActiveAuthorizationScope.SaveItemAsync();
                    }
                    await ReloadAsync();
                }
                catch (System.Exception ex)
                {
                    task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
                }
                if (task != null)
                    await task;
            }
        }

        #endregion
        #region SelectTreeItemCommand

        public ICommand SelectTreeItemCommand
        {
            get
            {
                return new MvxCommand(async () => await SelectTreeItemAsync());
            }
        }

        #endregion
        #region SelectTreeItemAsync

        public async Task SelectTreeItemAsync()
        {
            Task task = null;
            using (var busyManager = new BusyManager(this))
            {
                try
                {
                    if (this.ActiveTreeItem == null)
                    {
                        this.ActiveAuthorizationScope = null;
                    }
                    else if (this.ActiveTreeItem.IsServer)
                    {
                        this.ActiveServer = ServerConnection.GetServerConnection(this.ActiveTreeItem.ServerConnectionId);
                    }
                    else if (this.ActiveTreeItem.IsAuthorizationScope)
                    {
                        this.ActiveAuthorizationScope = await Sidvall.AuthorizationManager.UI.SystemContext.Current.DataPortal.AuthorizationScopeManager.GetItemAllIncludedAsync(this.ActiveTreeItem.ServerConnectionId,
                            this.ActiveTreeItem.AuthorizationScopeId.Value, 100, 100);
                        ShowResourceActionList();
                    }
                    InitializeJsonContent();
                }
                catch (System.Exception ex)
                {
                    task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
                }
                if (task != null)
                    await task;
            }
        }

        #endregion

        #region AddUserCommand

        public ICommand AddUserCommand
        {
            get
            {
                return new MvxCommand(AddUser);
            }
        }

        #endregion
        #region AddUser

        public void AddUser()
        {
            AuthorizationScopeUser item;

            if (this.ActiveAuthorizationScope == null)
                return;

            item = new AuthorizationScopeUser()
            {
                IsActive = true,
            };
            this.ActiveAuthorizationScope.AuthorizationScopeUsers.Add(item);
        }

        #endregion
        #region DeleteUserCommand

        public ICommand DeleteUserCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeUser>(DeleteUser);
            }
        }

        #endregion
        #region DeleteUser

        public void DeleteUser(AuthorizationScopeUser item)
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            if (item == null)
                return;
            this.ActiveAuthorizationScope.AuthorizationScopeUsers.Remove(item);
        }

        #endregion
        #region EditUserCommand

        public ICommand EditUserCommand
        {
            get
            {
                return new MvxCommand<AuthorizationScopeUser>(EditUser);
            }
        }

        #endregion
        #region EditUser

        public void EditUser(AuthorizationScopeUser item)
        {
            if (this.ActiveAuthorizationScope == null)
                return;
            if (item == null)
                return;
            this.ActiveUser = item;
            this.UserListIsVisible = false;
        }

        #endregion
        #region ShowUserListCommand

        public ICommand ShowUserListCommand
        {
            get
            {
                return new MvxCommand(ShowUserList);
            }
        }

        #endregion
        #region ShowUserList

        public void ShowUserList()
        {
            this.UserListIsVisible = true;
        }

        #endregion
        #region InitializeActiveUser

        public void InitializeActiveUser()
        {
            if (this.ActiveUser != null)
            {
                this.ActiveUserClaims = ClaimCollection.Deserialize(_ActiveUser.UserClaims, new ClaimCollection());
                this.ActiveUserContext = _ActiveUser.UserContext;
            }
            else
            {
                this.UserListIsVisible = true;

            }
        }

        #endregion

        #region AddUserClaimCommand

        public ICommand AddUserClaimCommand
        {
            get
            {
                return new MvxCommand(AddUserClaim);
            }
        }

        #endregion
        #region AddUserClaim

        public void AddUserClaim()
        {
            Claim item;

            if (this.ActiveUserClaims == null)
                return;

            item = new Claim()
            {
                ClaimType = Sidvall.Security.ClaimTypes.Role,
            };
            this.ActiveUserClaims.Add(item);
            OnUserClaimsChanged();
        }

        #endregion
        #region DeleteUserClaimCommand

        public ICommand DeleteUserClaimCommand
        {
            get
            {
                return new MvxCommand<Claim>(DeleteUserClaim);
            }
        }

        #endregion
        #region DeleteUserClaim

        public void DeleteUserClaim(Claim item)
        {
            if (this.ActiveUserClaims == null)
                return;
            if (item == null)
                return;
            this.ActiveUserClaims.Remove(item);
            OnUserClaimsChanged();
        }

        #endregion
        #region OnUserClaimsChanged

        public void OnUserClaimsChanged()
        {
            if (this.ActiveUserClaims == null)
                return;
            this.ActiveUser.UserClaims = this.ActiveUserClaims.Serialize();
        }

        #endregion

        #region ReloadAsync

        public async Task ReloadAsync()
        {
            Task task = null;
            try
            {
                if (this.TreeItems == null)
                    return;
                await this.TreeItems.ReloadAsync();
                InitializeJsonContent();
                InitializeActiveUser();
            }
            catch (System.Exception ex)
            {
                task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
            }
            if (task != null)
                await task;
        }

        #endregion
        #region StartAsync

        protected override async Task StartAsync()
        {
            _AuthorizationScopeIsVisible = false;
            _ResourceActionListIsVisible = true;
            _ResourceItemListIsVisible = true;
            _UserListIsVisible = true;

            this.AuthorizationContext = new AuthorizationContext();
            this.TreeItems = TreeItemCollection.GetTreeItemCollection();
            this.ResourceActionOptions = ActionOptionCollection.NewResourceActionOptions();
            this.ResourceItemActionOptions = ActionOptionCollection.NewResourceItemActionOptions();
            Sidvall.AuthorizationManager.Data.ClaimManager.Initialize(this.ValidClaims);
            Sidvall.AuthorizationManager.Data.ClaimManager.InitializeUserClaims(this.ValidUserClaims);

            await ReloadAsync();
        }

        #endregion

        #endregion
        #region Private Members

        private bool _AuthorizationScopeIsVisible = true;
        private bool _ResourceActionListIsVisible = true;
        private bool _ResourceItemListIsVisible = true;
        private bool _UserListIsVisible = false;

        #region DeleteTreeItemAsync

        private async Task DeleteTreeItemAsync(TreeItem item)
        {
            Task task = null;
            if (item == null)
                return;
            if (item.IsServer)
                return;
            using (var busyManager = new Sidvall.Data.BusyManager(this))
            {
                try
                {
                    var message = await Sidvall.UI.SystemContext.Current.DialogManager.ShowYesNoMessageAsync("Remove item: " + item.Name, "Are you sure?",
                           Sidvall.UI.Dialogs.MessageType.Question, false);
                    if (!message.AnswerIsYes)
                        return;
                    if (item.IsAuthorizationScope)
                    {
                        await Sidvall.AuthorizationManager.SystemContext.Current.DataPortal.AuthorizationScopeManager.DeleteItemByPrimaryKeyAsync(item.ServerConnectionId,
                            item.AuthorizationScopeId.Value);
                        if ((this.ActiveAuthorizationScope != null) && (this.ActiveAuthorizationScope.AuthorizationScopeId == item.AuthorizationScopeId))
                            this.ActiveAuthorizationScope = null;
                        await ReloadAsync();
                    }
                }
                catch (System.Exception ex)
                {
                    task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Error", ex);
                }
                if (task != null)
                    await task;
            }
        }

        #endregion
        #region InitializeTreeItem

        private void InitializeTreeItem()
        {
            RaisePropertyChanged("ActiveServer");
            RaisePropertyChanged("ActiveAuthorizationScope");
            RaisePropertyChanged("InformationIsVisible");
            RaisePropertyChanged("ServerIsVisible");
            RaisePropertyChanged("AuthorizationScopeIsVisible");
            RaisePropertyChanged("CanSave");
            RaisePropertyChanged("CanDelete");
            RaisePropertyChanged("CanAddTreeItem");
            RaisePropertyChanged("CanEditResourceActions");
            RaisePropertyChanged("AddTreeItemCaption");
        }

        #endregion

        #region OnActiveUserClaimsChildChanged

        private void OnActiveUserClaimsChildChanged(object sender, Sidvall.Business.ChildChangedEventArgs e)
        {
            OnUserClaimsChanged();
        }

        #endregion
        #region OnActiveAuthorizationScopePropertyChanged

        private void OnActiveAuthorizationScopePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            RaisePropertyChanged("CanSave");
            RaisePropertyChanged("CanEditResourceActions");
        }

        #endregion
        #region OnTreeItemsCollectionChanging

        private async void OnTreeItemsCollectionChanging(object sender, Sidvall.Business.CollectionChangedEventArgs e)
        {
            if (e.Action == Sidvall.Business.CollectionChangedAction.RemoveItem)
            {
                await DeleteTreeItemAsync(e.Item as TreeItem);
                e.Cancel = true;
            }
        }

        #endregion

        #endregion
    }
}